using System;
using System.ComponentModel;
using System.Globalization;
using System.Text.RegularExpressions;
using Microsoft.WowAddonStudio.FrameXml.Serialization.TypeConverters;
using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Serialization.Tests.TypeConvertersTests
{
	[TestFixture]
	public sealed class InsetTypeConverterTest
	{
		private static readonly char listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator[0];
		private static Regex insetStringRegex;
		private TypeConverter typeConverter;

		#region Setup/Teardown

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			string regExstring = String.Concat(@"^((\d+)", listSeparator, @"){3}((\d+)", listSeparator, @"{0,1}){1}$");
			insetStringRegex = new Regex(regExstring, RegexOptions.Compiled);
		}

		[SetUp]
		public void SetUp()
		{
			typeConverter = new InsetTypeConverter();
		}

		[TearDown]
		public void TearDown()
		{
		}

		#endregion

		[Test(Description = "")]
		public void Test_SimpleConvertTo()
		{
			var inset = new Inset {Left = 10, Right = 20, Top = 30, Bottom = 40};
			object convertTo = typeConverter.ConvertTo(null, CultureInfo.CurrentCulture, inset, typeof (string));
			Assert.IsNotNull(convertTo);
			Assert.IsInstanceOfType(typeof(string), convertTo);
			Assert.AreEqual(String.Format(CultureInfo.CurrentCulture, "{0}{4}{1}{4}{2}{4}{3}", inset.Left, inset.Right, inset.Top, inset.Bottom, listSeparator), convertTo);
			
			convertTo = typeConverter.ConvertTo(null, CultureInfo.CurrentCulture, null, typeof(string));
			Assert.IsNotNull(convertTo);
			Assert.AreEqual(String.Empty, convertTo);
		}

		[Test(Description = "")]
		public void Test_SimpleConvertFrom()
		{
			var inset = new Inset { Left = 10, Right = 20, Top = 30, Bottom = 40 };
			string insetString = String.Format(CultureInfo.CurrentCulture, "{0}{4}{1}{4}{2}{4}{3}", inset.Left, inset.Right,
			                                   inset.Top, inset.Bottom, listSeparator);
			Console.WriteLine(insetString);
			object convertFrom = typeConverter.ConvertFrom(null, CultureInfo.CurrentCulture, insetString);
			Assert.IsNotNull(convertFrom);
			Assert.IsInstanceOfType(typeof(Inset), convertFrom);
			inset = (Inset) convertFrom;
			Assert.AreEqual(10,inset.Left);
			Assert.AreEqual(20,inset.Right);
			Assert.AreEqual(30,inset.Top);
			Assert.AreEqual(40,inset.Bottom);
		}

		[Test(Description = "")]
		public void Test_ConvertFromSingleValue()
		{
			object convertFrom = typeConverter.ConvertFrom(null, CultureInfo.CurrentCulture, 10.ToString());
			Assert.IsNotNull(convertFrom);
			Assert.IsInstanceOfType(typeof(Inset), convertFrom);
			var texCoords = (Inset)convertFrom;
			Assert.AreEqual(10f, texCoords.Left);
			Assert.AreEqual(10f, texCoords.Right);
			Assert.AreEqual(10f, texCoords.Top);
			Assert.AreEqual(10f, texCoords.Bottom);
		}

		[Test(Description = "")]
		[ExpectedException(typeof(ArgumentException))]
		public void Test_SimpleConvertFromFailed()
		{
			typeConverter.ConvertFrom(null, CultureInfo.CurrentCulture, "441wer,erytrty");
		}

		[Test(Description = "")]
		[ExpectedException(typeof(NotSupportedException))]
		public void Test_SimpleConvertFromFromEmptyValue()
		{
			typeConverter.ConvertFrom(null, CultureInfo.CurrentCulture, null);
		}
		
		[Test(Description = "")]
		public void Test_InsetRegex()
		{
			var textValue = "100" + listSeparator + "20" + listSeparator + "100" + listSeparator + "200";
			Assert.IsTrue(Match(textValue));

			textValue = "100" + listSeparator + "20" + listSeparator + "100" + listSeparator + "200" + listSeparator;
			Assert.IsTrue(Match(textValue));

			textValue = "100|" + "20" + listSeparator + "100" + listSeparator + "200";
			Assert.IsFalse(Match(textValue));

			textValue = "100" + listSeparator + "20" + listSeparator + "100" + listSeparator;
			Assert.IsFalse(Match(textValue));

			textValue = "100" + listSeparator + "xc" + listSeparator + "100" + listSeparator + "200";
			Assert.IsFalse(Match(textValue));
		}

		/// <summary>
		/// Matches the specified text.
		/// </summary>
		/// <param name="text">The text.</param>
		/// <returns></returns>
		private static bool Match(string text)
		{
			Match match = insetStringRegex.Match(text);
			return match.Success;
		}
	}
}